package org.dromara.web.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.web.domain.Market;
import org.dromara.web.domain.Stock;
import org.dromara.web.domain.SysJob;
import org.dromara.web.domain.bo.MarketBo;
import org.dromara.web.domain.vo.MarketVo;
import org.dromara.web.mapper.MarketMapper;
import org.dromara.web.service.ApiService;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;


import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

@Service
@RequiredArgsConstructor
@Slf4j
public class ApiServiceImpl implements ApiService {

    @Value("${juhe.api.apikey}")
    private String apikey;
    private final RestTemplate restTemplate;

    private final MarketMapper baseMapper;

    private final ObjectMapper objectMapper;

    // 用于跟踪当前批次的起始页码
    private static final AtomicInteger currentStartPage = new AtomicInteger(1);

    // 多线程 + 计时器
    @Override
    public String getStock() throws InterruptedException {
        // 获取当前批次起始页码
        int start = currentStartPage.getAndAdd(5);
        log.info("开始处理页码 {}-{}", start, start + 4);
        // 使用线程池来管理任务
        ExecutorService executorService = Executors.newFixedThreadPool(5); // 创建一个固定大小的线程池
        List<CompletableFuture<Void>> futures = new ArrayList<>(); // 用于存储所有任务的Future
        // 创建5个异步任务
        for (int i = 0; i < 5; i++) {
            int page = start + i;
            // 提交任务到线程池
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                try {
                    getMarketData(page); // 调用API方法获取数据
                    log.debug("页码 {} 处理完成", page);
                } catch (Exception e) {
                    log.error("页码 {} 处理异常", page, e);
                }
            }, executorService);
            futures.add(future);
        }
        // 等待所有任务完成
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

        // 关闭线程池
        executorService.shutdown();
        return String.format("已处理页码 %d-%d 的数据", start, start + 4);
    }

    /**
     * 根据id查询market
     *
     * @param id 主键
     * @return
     */
    @Override
//    @Tool("根据id查询market")
    public MarketVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询market信息
     *
     * @param bo 查询条件
     * @return
     */
    @Override

    public List<MarketVo> queryList(MarketBo bo) {
        LambdaQueryWrapper<Market> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 新增Market信息
     *
     * @param bo Market信息
     * @return
     */
    @Override
    public Boolean insertByBo(MarketBo bo) {
        Market add = MapstructUtils.convert(bo, Market.class);
//        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改Market信息
     *
     * @param bo Market信息
     * @return
     */
    @Override
    public Boolean updateByBo(MarketBo bo) {
        Market update = MapstructUtils.convert(bo, Market.class);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 删除Market信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 获取所有股票代码
     *
     * @return
     */
    @Override
//    @Tool("获取所有股票代码（symbol）")
    public List<String> listSymbols() {
        LambdaQueryWrapper<Market> wrapper = Wrappers.lambdaQuery();
        wrapper.select(Market::getSymbol).groupBy(Market::getSymbol);
        return baseMapper.selectObjs(wrapper).stream()
            .map(obj -> (String) obj)
            .toList();

    }

    // 计时器清零
    @Override
    public void resetStartPage() {
        // 清零当前批次起始页码
        currentStartPage.set(1);
    }

    /**
     * 获取市场数据
     *
     * @param page 页码
     * @return 市场数据
     */
    @Override
    public String getMarketData(int page) {
        log.info("开始请求第 {} 页数据", page);
        Map<String, String> map = new HashMap<>();
        map.put("key", apikey);
        map.put("page", String.valueOf(page));
        String apiUrl = "http://web.juhe.cn/finance/stock/usaall";

        // 构建查询参数
        StringBuilder query = new StringBuilder();
        map.forEach((key, value) -> {
            if (!query.isEmpty()) {
                query.append("&");
            }
            query.append(key).append("=").append(value);
        });

        String url = apiUrl + "?" + query.toString();

        try {
            ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);
            String apiResponse = response.getBody();
            // 解析并保存数据
            parseAndSaveMarketData(apiResponse);
            return apiResponse;
        } catch (Exception e) {
            log.error("请求API失败", e);
            throw new RuntimeException("请求API失败", e);
        }
    }
    /**
     * 新增BigDecimal安全转换方法
     *
     * @param node  JsonNode
     * @param field 字段名
     * @return BigDecimal
     */
    private BigDecimal parseBigDecimal(JsonNode node, String field) {
        String value = node.path(field).asText("0").replaceAll("[^\\d.]", "");
        try {
            return new BigDecimal(value);
        } catch (NumberFormatException e) {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 查询指定的market信息
     *+
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return
     */
    @Override
//    @Tool("根据股票代码symbol查询信息")
    public TableDataInfo<MarketVo> queryPageList(MarketBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<Market> lqw = buildQueryWrapper(bo);
        Page<MarketVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 解析JSON数据并保存到数据库
     *
     * @param apiResponse API返回的JSON数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void parseAndSaveMarketData(String apiResponse) {
        try {
            JsonNode jsonNode = objectMapper.readTree(apiResponse);
            JsonNode dataNode = jsonNode.path("result").path("data");
            List<Market> markets = new ArrayList<>();

            for (JsonNode marketNode : dataNode) {
                MarketBo marketBo = new MarketBo();

                marketBo.setCname(marketNode.path("cname").asText());
                marketBo.setCategory(marketNode.path("category").asText());
                marketBo.setSymbol(marketNode.path("symbol").asText());
                marketBo.setMarket(marketNode.path("market").asText());

                marketBo.setPrice(parseBigDecimal(marketNode, "price"));
                marketBo.setDiff(parseBigDecimal(marketNode, "diff"));
                marketBo.setChg(parseBigDecimal(marketNode, "chg"));
                marketBo.setPreclose(parseBigDecimal(marketNode, "preclose"));
                marketBo.setOpen(parseBigDecimal(marketNode, "open"));
                marketBo.setHigh(parseBigDecimal(marketNode, "high"));
                marketBo.setLow(parseBigDecimal(marketNode, "low"));
                marketBo.setAmplitude(parseBigDecimal(marketNode, "amplitude"));
                marketBo.setVolume(parseLong(marketNode, "volume"));
                marketBo.setMktcap(parseBigDecimal(marketNode, "mktcap"));

                markets.add(MapstructUtils.convert(marketBo, Market.class));
            }

            if (!markets.isEmpty()) {
                baseMapper.insertBatch(markets); // 批量插入
//                validEntityBeforeSave();// 保存前的数据校验
            }
        } catch (Exception e) {
            log.error("解析API数据失败", e);
            throw new RuntimeException("解析API数据失败", e);
        }
    }


    /**
     * 按照id排序
     *
     * @param bo
     * @return
     */
    private LambdaQueryWrapper<Market> buildQueryWrapper(MarketBo bo) {
        LambdaQueryWrapper<Market> lqw = Wrappers.lambdaQuery();
//        lqw.orderByAsc(Market::getId);
        // 动态排序逻辑（新增）
        if (StringUtils.isNotBlank(bo.getSortField())) {
            if ("asc".equalsIgnoreCase(bo.getSortOrder())) {
                lqw.orderByAsc(StringUtils.isNotBlank(bo.getSortField()),
                    getSortColumn(bo.getSortField()));
            } else {
                lqw.orderByDesc(StringUtils.isNotBlank(bo.getSortField()),
                    getSortColumn(bo.getSortField()));
            }
        } else {
            // 默认排序（原写死的排序）
            lqw.orderByAsc(Market::getId);
        }
        lqw.like(StringUtils.isNotBlank(bo.getCname()), Market::getCname, bo.getCname());
        lqw.like(StringUtils.isNotBlank(bo.getCategory()), Market::getCategory, bo.getCategory());
        lqw.like(StringUtils.isNotBlank(bo.getSymbol()), Market::getSymbol, bo.getSymbol());
        return lqw;
    }

    // 新增字段映射方法（安全校验）
    private SFunction<Market, ?> getSortColumn(String fieldName) {
        Map<String, SFunction<Market, ?>> allowedFields = new HashMap<>();
        allowedFields.put("id", Market::getId);
        allowedFields.put("time", Market::getTime);
        allowedFields.put("price", Market::getPrice);
        allowedFields.put("volume", Market::getVolume);
        // 添加其他允许排序的字段...

        return allowedFields.getOrDefault(fieldName.toLowerCase(), Market::getId);
    }


    /**
     * 解析Long类型数据
     *
     * @param node  JsonNode
     * @param field 字段名
     * @return
     */
    private Long parseLong(JsonNode node, String field) {
        String value = node.path(field).asText("");
        if (StringUtils.isEmpty(value)) {
            return 0L;
        }
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            return 0L;
        }
    }
}
